<?php

namespace otherLibrary;

class CurlFTPClient {
    private $ftpServer;      // FTP服务器地址
    private $ftpUsername;    // FTP登录用户名
    private $ftpPassword;    // FTP登录密码
    private $connId;         // cURL资源句柄

    public function __construct($ftpServer, $ftpUsername, $ftpPassword) {
        $this->ftpServer = $ftpServer;
        $this->ftpUsername = $ftpUsername;
        $this->ftpPassword = $ftpPassword;
    }

    public function connect() {
        $this->connId = curl_init();
        if ($this->connId === false) {
            echo "无法初始化cURL\n";
            return false;
        }

        curl_setopt($this->connId, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($this->connId, CURLOPT_USERPWD, "{$this->ftpUsername}:{$this->ftpPassword}");
        curl_setopt($this->connId, CURLOPT_USE_SSL, false);
        return true;
    }

    public function disconnect() {
        if ($this->connId) {
            curl_close($this->connId);
            echo "已断开与FTP服务器的连接\n";
        }
    }

    public function processFiles($remoteDir, $localRootDir) {
        if (!$this->changeDir($remoteDir)) {
            return false;
        }

        $fileList = $this->getFileList();
        foreach ($fileList as $file) {
            if (pathinfo($file, PATHINFO_EXTENSION) == 'status') {
//                dd($file);
                $baseName = pathinfo($file, PATHINFO_FILENAME);
                $targetFile = $remoteDir . '/' . $baseName;

                $actualFile = $remoteDir . '/' . $baseName;
                if ($this->isValidFile($actualFile)) {

                    if ($this->deleteFile($remoteDir . '/' . $baseName . '.status')) {
                        // 等待一段时间确保文件已被删除
                        sleep(1);

                        $localDir = $this->createLocalDir($localRootDir);

                        $localPath = $localDir . '/' . $baseName;
                        if ($this->downloadFile($actualFile, $localPath)) {
                            echo "成功下载 $actualFile 到 $localPath\n";

                            $this->deleteFile($targetFile);

                            // 确保文件不存在后再创建
                            if (!$this->fileExists($remoteDir . '/' . $baseName . '.status') && $this->createEmptyFile($remoteDir, $baseName . '.status')) {
                                echo "在FTP上成功创建 {$remoteDir}/{$baseName}.status\n";
                            } else {
                                echo "在FTP上创建 {$remoteDir}/{$baseName}.status 失败\n";
                            }
                        } else {
                            echo "下载 $actualFile 失败\n";
                        }
                    } else {
                        echo "删除 {$remoteDir}/{$baseName}.status 失败\n";
                    }

                } else {
                    echo "文件 $actualFile 不存在或为空\n";
                }
            }
        }
    }

    private function changeDir($remoteDir) {
        curl_setopt($this->connId, CURLOPT_URL, "ftp://{$this->ftpServer}/");
        curl_setopt($this->connId, CURLOPT_CUSTOMREQUEST, 'CWD ' . $remoteDir);
        $response = curl_exec($this->connId);
//        if ($response === false) {
//            echo "无法切换到目录 $remoteDir\n";
//            return false;
//        }
        return true;
    }

    private function getFileList() {
        curl_setopt($this->connId, CURLOPT_CUSTOMREQUEST, 'NLST');
        $response = curl_exec($this->connId);

        if ($response === false) {
            echo "无法获取目录列表\n";
            return [];
        }
        $files = array_filter(explode("\n", trim($response)), function($file) {
            $file = trim($file);
            return $file !== '.' && $file !== '..';
        });
        return array_values($files);
    }

    private function isValidFile($remoteFile) {
        $curlHandle = curl_init();
        curl_setopt_array($curlHandle, array(
            CURLOPT_URL => "ftp://{$this->ftpServer}{$remoteFile}",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_USERPWD => "{$this->ftpUsername}:{$this->ftpPassword}",
            CURLOPT_TIMEOUT => 30,
            CURLOPT_USE_SSL => false,
            CURLOPT_NOBODY => true,
        ));

        curl_exec($curlHandle);
        $fileSize = curl_getinfo($curlHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
        curl_close($curlHandle);

        return $fileSize > 0;
    }

    private function deleteFile($remoteFile) {
        $curlHandle = curl_init();
        curl_setopt_array($curlHandle, array(
            CURLOPT_URL => "ftp://{$this->ftpServer}/{$remoteFile}",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_USERPWD => "{$this->ftpUsername}:{$this->ftpPassword}",
            CURLOPT_TIMEOUT => 30,
            CURLOPT_USE_SSL => false,
            CURLOPT_CUSTOMREQUEST => "RNFR {$remoteFile}",
            CURLOPT_VERBOSE => true, // 启用详细调试输出
        ));

        $response = curl_exec($curlHandle);
        $httpCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
        $curlError = curl_error($curlHandle);
        curl_close($curlHandle);

        if ($httpCode === 350) { // 350 表示 RNFR 成功
            $curlHandle = curl_init();
            curl_setopt_array($curlHandle, array(
                CURLOPT_URL => "ftp://{$this->ftpServer}/NUL",
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_USERPWD => "{$this->ftpUsername}:{$this->ftpPassword}",
                CURLOPT_TIMEOUT => 30,
                CURLOPT_USE_SSL => false,
                CURLOPT_CUSTOMREQUEST => "RNTO /dev/null", // Unix 系统使用 /dev/null, Windows 系统使用 NUL
                CURLOPT_VERBOSE => true, // 启用详细调试输出
            ));

            $response = curl_exec($curlHandle);
            $httpCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
            $curlError = curl_error($curlHandle);
            curl_close($curlHandle);

            if ($httpCode === 250) {
                return true;
            } else {
                echo "重命名文件失败: $remoteFile, HTTP Code: $httpCode, Response: $response, cURL Error: $curlError\n";
                return false;
            }
        } else {
            echo "删除文件失败: $remoteFile, HTTP Code: $httpCode, Response: $response, cURL Error: $curlError\n";
            return false;
        }
    }

    public function downloadFile($remoteFile, $localFile) {
        $curlHandle = curl_init();
        curl_setopt_array($curlHandle, array(
            CURLOPT_URL => "ftp://{$this->ftpServer}{$remoteFile}",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_USERPWD => "{$this->ftpUsername}:{$this->ftpPassword}",
            CURLOPT_TIMEOUT => 30,
            CURLOPT_USE_SSL => false,
            CURLOPT_BINARYTRANSFER => true,
        ));

        $fileData = curl_exec($curlHandle);
        curl_close($curlHandle);

        if ($fileData !== false) {
            if (file_put_contents($localFile, $fileData) !== false) {
                return true;
            } else {
                echo "保存文件到本地失败: $localFile\n";
            }
        } else {
            echo "下载文件失败: $remoteFile\n";
        }

        return false;
    }

    private function createEmptyFile($remoteDir, $fileName) {
        $url = "ftp://{$this->ftpUsername}:{$this->ftpPassword}@{$this->ftpServer}{$remoteDir}/{$fileName}";
        $handle = fopen($url, 'w');
        if ($handle !== false) {
            fclose($handle);
            return true;
        } else {
            return false;
        }
    }

    private function createLocalDir($localRootDir) {
        $dateTime = date('Y/m/d/Hi');
        $localDir = $localRootDir . '/' . $dateTime;
        if (!is_dir($localDir)) {
            mkdir($localDir, 0777, true);
        }
        return $localDir;
    }

    private function fileExists($remoteFile) {
        $curlHandle = curl_init();
        curl_setopt_array($curlHandle, array(
            CURLOPT_URL => "ftp://{$this->ftpServer}{$remoteFile}",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_USERPWD => "{$this->ftpUsername}:{$this->ftpPassword}",
            CURLOPT_TIMEOUT => 30,
            CURLOPT_USE_SSL => false,
            CURLOPT_NOBODY => true,
        ));

        curl_exec($curlHandle);
        $httpCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
        curl_close($curlHandle);

        return $httpCode === 200; // 200 表示文件存在
    }

}
